﻿using System.Linq;
using Coder.Workflow.ViewModel;
using Fee.Orders;
using Fee.Orders.DesignWorkflow;
using Fee.Orders.FormalWorkflow;
using Fee.Orders.ViewModel;
using Fee.Searchers;
using Fee.Stores;
using Identity;
using JwtWebApi.Data;
using JwtWebApi.Filters;
using JwtWebApi.Models;
using JwtWebApi.Models.ViewModel;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Cors;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace JwtWebApi.Controllers
{
    [Authorize]
    [Route("[controller]")]
    [ApiController]
    [EnableCors]
    public class FormalOrderController : Controller
    {
        private readonly IConstructionTaskStore<ApplicationDbContext> _constructionTask;
        private readonly ApplicationDbContext _context;
        private readonly IFormalOrderStore<ApplicationDbContext> _orderStore;
        private readonly FormalOrderManager<ApplicationDbContext> _orderManager;
        private readonly UserManager<User> _userManager;


        public FormalOrderController(FormalOrderManager<ApplicationDbContext> orderManager,
            ApplicationDbContext context, IConstructionTaskStore<ApplicationDbContext> constructionTask,
            IFormalOrderStore<ApplicationDbContext> orderStore,
            UserManager<User> userManager)


        {
            _orderManager = orderManager;
            _context = context;
            _constructionTask = constructionTask;

            _orderStore = orderStore;
            _userManager = userManager;
        }


        [HttpGet("list")]
        public IActionResult List([FromQuery] DelegateOrderSearch searcher)
        {
            var query = _orderStore.List(searcher, out var total);
            return Json(new
            {
                total,
                data = query
            });
        }


        [HttpGet("work-activity/{id:int}")]
        public IActionResult GetTask(int id)
        {
            var workflowInstanceItem = _orderManager.GetWorkActivity(id, true);

            var result = new WorkActivityViewData<OrderViewModel>(workflowInstanceItem)
            {
                ProcessInstance = new FormalOrderViewModel((FormalOrder)workflowInstanceItem.ProcessInstance)
            };
            return Json(result);
        }

        [HttpPut("save/{id:int}")]
        public IActionResult Save([FromBody] FormalOderModel data, [FromRoute] int id)
        {
            var usr = _context.GetByUserName(User.Identity.Name);
            var fr = _orderManager.GetCurrentWorkActivity(id, usr);

            if (!fr.Any())
                return Ok(new
                {
                    successed = false,
                    message = "工作已经完成"
                });
            var order = _orderManager.GetById(id);
            var activity = fr.First();
            if (activity.DepositUser.Id != usr.Id && order.User.Id != usr.Id)
                return Unauthorized(new
                {
                    successed = false,
                    message = "不是你的工作"
                });

            _context.Entry(order).Collection(_ => _.PlanCosts).Load();
            order.UpdateBy(data.PlanCosts);
            order.UpdateBy(data.Details.Select(f => f.ToDelegateOrderDetail(_context)));

            _context.Update(order);
            _context.SaveChanges();
            return Json(new
            {
                successed = true,
                message = "保存成功"
            });
        }

        [HttpGet("get/{id:int}")]
        public IActionResult Get([FromRoute] int id)
        {

            var order = _orderManager.GetById(id);
            //var iem = _orderStore.GetById(id);
            return Json(order);
        }


        [HttpPut("save/details/{id:int}")]
        public IActionResult SaveDetail([FromBody] DelegateOrderData data, [FromRoute] int id)
        {
            var usr = _context.GetByUserName(User.Identity.Name);
            var fr = _orderManager.GetCurrentWorkActivity(id, usr);

            if (!fr.Any())
                return Ok(new
                {
                    successed = false,
                    message = "工作已经完成"
                });
            var order = _orderStore.GetById(id);
            var activity = fr.FirstOrDefault();
            if (activity.DepositUser.Id != usr.Id && order.User.Id != usr.Id)
                return Unauthorized(new
                {
                    successed = false,
                    message = "不是你的工作"
                });


            order.UpdateBy(data.Details.Select(f => f.ToDelegateOrderDetail(_context)));
            _context.Update(order);
            _context.SaveChanges();
            return Json(new
            {
                successed = true,
                message = "保存成功"
            });
        }


        [HttpPost("reject/{id:int}")]
        [ModelValidteFilter]
        public IActionResult Reject([FromRoute] int id, [FromBody] WorkflowDepositViewModel model)
        {
            _orderManager.Reject(id, model.Comment, out var workActivities);
            return Json(new
            {
                successed = true,
                message = true ? "处理成功" : "没有可以退回流程"
            });
        }

        [HttpPost("resolve/{id:int}")]
        [ModelValidteFilter]
        public IActionResult Resolve([FromRoute] int id, [FromBody] WorkflowDepositViewModel model)
        {
            _orderManager.Resolve(id, model.Comment, out var workActivities);
            return Json(new
            {
                successed = true,
                message = "处理成功"
            });
        }

        [HttpPost("create")]
        public IActionResult Create([FromBody] CreateDelegateOrderVieweModel model)
        {
            var user = _userManager.GetUserAsync(User);
            var task = _constructionTask.Get(model.TaskId);

            _orderManager.CreateOrTryToStart(task, user.Result);
            return Json(new
            {
                succssed = true,
                message = "创建成功"
            });
        }


        [HttpGet("myTask")]
        public IActionResult GetMyTask([FromQuery] DelegateWorkActivitySearch searcher)
        {
            var task
                = _orderManager.GetMyTask(searcher, out var total);

            return Json(new
            {
                data = task,
                total
            });
        }
    }
}